<!-- components/TkiQrCode/TkiQrCode.vue -->
<template>
	<view :style="{ width: size + 'px', height: size + 'px' }" class="container">
		<canvas
			:canvas-id="canvasId"
			:id="canvasId"
			:width="canvasWidth"
			:height="canvasHeight"
			class="qrCodeCanvas"
		/>
	</view>
</template>

<script>
function qrCode(text) {
	const n = 21;
	const matrix = Array(n)
		.fill()
		.map(() => Array(n).fill(true));
	const set = (r, c, v) => {
		if (r >= 0 && r < n && c >= 0 && c < n) matrix[r][c] = v;
	};

	// 定位角 (7x7)
	const drawProbe = (r, c) => {
		for (let i = 0; i < 7; i++) {
			for (let j = 0; j < 7; j++) {
				if (
					i === 0 ||
					i === 6 ||
					j === 0 ||
					j === 6 ||
					(i >= 2 && i <= 4 && j >= 2 && j <= 4)
				) {
					set(r + i, c + j, false);
				}
			}
		}
	};
	drawProbe(0, 0);
	drawProbe(0, n - 7);
	drawProbe(n - 7, 0);

	// 简单数据填充
	for (let i = 8; i < n - 8; i++) {
		for (let j = 8; j < n; j++) {
			if ((i + j) % 3 === 0) set(i, j, false);
		}
	}
	return { data: matrix, width: n, height: n };
}

export default {
	name: 'TkiQrCode',
	props: {
		value: { type: String, required: true },
		size: { type: Number, default: 200 },
		canvasId: { type: String, default: 'tki-qrcode-canvas' },
		margin: { type: Number, default: 1 },
		background: { type: String, default: '#FFFFFF' },
		foreground: { type: String, default: '#000000' },
		autoMake: { type: Boolean, default: true },
		logo: { type: String, default: '' },
		logoSize: { type: Number, default: 0.2 },
		logoBackgroundColor: { type: String, default: null },
		logoCornerRadius: { type: Number, default: 4 },
	},

	data() {
		return {
			dpr: 1,
			canvasWidth: this.size,
			canvasHeight: this.size,
		};
	},

	mounted() {
		this.init();
	},

	methods: {
		init() {
			const res = uni.getSystemInfoSync();
			this.dpr = res.pixelRatio || 1;
			this.canvasWidth = this.size * this.dpr;
			this.canvasHeight = this.size * this.dpr;

			if (this.autoMake) {
				this.$nextTick(() => {
					setTimeout(() => {
						this.make();
					}, 500);
				});
			}
		},

		async make() {
			if (!this.value) return;

			// ✅ 1. 创建上下文
			const ctx = uni.createCanvasContext(this.canvasId, this);

			const qr = qrCode(this.value);
			const n = 21;
			const blockSize = Math.floor(this.size / n);
			const marginPx = this.margin * blockSize;

			// ✅ 2. 清空并画背景
			ctx.clearRect(0, 0, this.size, this.size);
			ctx.setFillStyle(this.background);
			ctx.fillRect(0, 0, this.size, this.size);

			// ✅ 3. 画二维码
			ctx.setFillStyle(this.foreground);
			for (let row = 0; row < n; row++) {
				for (let col = 0; col < n; col++) {
					if (!qr.data[row][col]) {
						const x = col * blockSize + marginPx;
						const y = row * blockSize + marginPx;
						ctx.fillRect(x, y, blockSize, blockSize);
					}
				}
			}

			// ✅ 4. 准备 Logo
			if (this.logo) {
				let tmpPath = this.logo;
				try {
					if (this.logo.startsWith('http')) {
						const download = await uni.downloadFile({ url: this.logo });
						tmpPath = download.tempFilePath;
					}

					const contentSize = this.size - 2 * marginPx;
					const logoWidth = contentSize * this.logoSize;
					const logoHeight = contentSize * this.logoSize;
					const logoX = marginPx + (contentSize - logoWidth) / 2;
					const logoY = marginPx + (contentSize - logoHeight) / 2;

					// 画背景（可选）
					if (this.logoBackgroundColor) {
						ctx.setFillStyle(this.logoBackgroundColor);
						this.roundRect(
							ctx,
							logoX,
							logoY,
							logoWidth,
							logoHeight,
							this.logoCornerRadius
						);
						ctx.fill();
					}

					// ✅ 画 Logo
					ctx.drawImage(tmpPath, logoX, logoY, logoWidth, logoHeight);
				} catch (err) {
					console.error('Logo 加载失败:', err);
					this.$emit('logoError', err);
				}
			}

			// ✅ 5. 最终绘制（所有操作完成后一次 draw）
			ctx.draw(false, () => {
				this.$emit('made');
				this.save();
			});
		},

		roundRect(ctx, x, y, w, h, r) {
			r = Math.min(r, w / 4, h / 4);
			ctx.beginPath();
			ctx.moveTo(x + r, y);
			ctx.arcTo(x + w, y, x + w, y + h, r);
			ctx.arcTo(x + w, y + h, x, y + h, r);
			ctx.arcTo(x, y + h, x, y, r);
			ctx.arcTo(x, y, x + w, y, r);
			ctx.closePath();
		},

		save() {
			uni.canvasToTempFilePath(
				{
					canvasId: this.canvasId,
					x: 0,
					y: 0,
					width: this.size,
					height: this.size,
					destWidth: this.size * this.dpr,
					destHeight: this.size * this.dpr,
					success: res => {
						this.$emit('result', res.tempFilePath);
					},
					fail: err => {
						console.error('导出失败:', err);
						this.$emit('result', null);
					},
				},
				this
			);
		},
	},
};
</script>

<style scoped>
.container {
	position: relative;
	display: inline-block;
}
.qrCodeCanvas {
	width: 100%;
	height: 100%;
}
</style>
